package org.ccay.core.util;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

/**
 * 文件工具类
 * 
 * 
 * @since 2012-1-31
 */
public final class FileUtil {
	
	/**
	 * 避免创建实例
	 */
	private FileUtil(){		
	}
	
	/** 
	 * Java文件操作 获取文件扩展名
	 * @param filename
	 * @return
	 */
	public static String getExtension(String filename) {
		if ((filename != null) && (filename.length() > 0)) {
			int dot = filename.lastIndexOf('.');
			if ((dot > -1) && (dot < (filename.length() - 1))) {
				return filename.substring(dot + 1).toLowerCase(Locale.ENGLISH);
			}
		}
		return filename;
	}
 
	/** 
	 * Java文件操作 获取不带扩展名的文件名
	 * @param filename
	 * @return
	 */
	public static String getFileNameNoEx(String filename) {
		if ((filename != null) && (filename.length() > 0)) {
			int dot = filename.lastIndexOf('.');
			if ((dot > -1) && (dot < (filename.length()))) {
				return filename.substring(0, dot);
			}
		}
		return filename;
	}
	/** 
	 * Java文件操作 获取路径中的文件名
	 * @param filename
	 * @return
	 */
	public static String getFileName(String file) {
		if(StringUtil.isNullOrEmpty(file)){
			return file;
		}
		int dotEx = file.lastIndexOf('.');
		if(dotEx == -1){
			return file;
		}
		int dot = file.lastIndexOf('\\');
		if ((dot > -1) && (dot < (file.length()))) {
			return file.substring(dot+1, file.length());
		}
		return file;
	}
	/**
	 * 验证是否合法文件名称
	 * @param fileName
	 * @return
	 * Created：2013-7-20
	 * @author chaowangbang
	 */
	public static String validateFileName(String fileName){
		if(StringUtil.isNullOrEmpty(fileName)){
			return "";
		}
		String PILENAME_PATTERN = "[\\\\/:*?\"<>|]";
		Pattern pattern=Pattern.compile(PILENAME_PATTERN);
		Matcher matcher=pattern.matcher(fileName);
		if(matcher.find()){
			return "forbidden-character code";
		}
		return fileName;
	}   
	
	/**
	 * * 把zip文件解压到指定路径
	 * @param targetPath 解压到的文件路径
	 * @param zipFilePath 要解压的文件
	 * @throws IOException
	 * Created：2013-8-5
	 * @author chaowangbang
	 */
	public static void decompressZipFile(String targetPath, String zipFilePath) throws IOException {
		ZipInputStream zipInStream = null;
		InputStream fileInStream = null;
		OutputStream zipOutStream = null;
		File tempFile = null;
		File tempDirFile = null;
		try {
			fileInStream = new FileInputStream(zipFilePath);
			zipInStream = new ZipInputStream(fileInStream);
			ZipEntry entry = null;
 			while ((entry = zipInStream.getNextEntry()) != null) {
				String zipPath = entry.getName();
				//如果是目录 那么创建目录
				if (entry.isDirectory()) {
					tempDirFile = new File(targetPath + File.separator
							+ zipPath);
					if (!tempDirFile.exists()) {
						tempDirFile.mkdirs();
					}
				//如果是文件 那么创建文件
				} else {
					tempFile = new File(targetPath + File.separator + zipPath);
					if (!tempFile.exists()) {
						tempDirFile = tempFile.getParentFile();
						tempDirFile.mkdirs();
						tempFile.createNewFile();
					}
					zipOutStream = new FileOutputStream(tempFile);
					StreamUtil.transfer(zipInStream, zipOutStream,false);
					StreamUtil.closeStreams(zipOutStream);
				}
 			}
		}finally {
			tempFile = null;
			tempDirFile = null;
			StreamUtil.closeStreams(zipInStream,fileInStream,zipOutStream);
		}
	}
	

	/**
	 * 	 * 压缩文件
	 * @param sourceDir 要压缩的文件夹
	 * @param zipFileName 压缩文件名
	 * @param sourceDir
	 * @param zipFileName
	 * Created：2013-8-6
	 * @author chaowangbang
	 * @throws IOException 
	 */
	public static void createZipFile(String sourceDir, String zipFileName) throws IOException{
		File folderObject = new File(sourceDir);
		if(!folderObject.exists()){
			return;
		}
		ZipOutputStream zipOutStream = null;
		try {
			//获取当前目录下的所有文件
			List<File> fileList = getDirFiles(new File(sourceDir));
			zipOutStream = new ZipOutputStream(new FileOutputStream(zipFileName));
			
			for (int i = 0; i < fileList.size(); i++) {
				File file = (File) fileList.get(i);
				
				String entryName = getAbsFileName(sourceDir, file);
				
				createZipEntry(entryName, zipOutStream, file);
			}
		} finally {
			StreamUtil.closeStreams(zipOutStream);
		}

	}
	
	/**
	 * 
	 * 得到文件的相对路径
	 * @param baseDir 参照的路径
	 * @param realFileName 文件
	 * @return 文件的相对路径
	 * @return
	 * Created：2013-8-6
	 * @author chaowangbang
	 */
	public static String getAbsFileName(String baseDir, File realFileName) {
		File real = realFileName;
		File base = new File(baseDir);
		String ret = real.getName();
		while (true) {
			real = real.getParentFile();
			if (real == null){
				break;
			}	
			if (real.equals(base)){
				break;
			}else {
				ret = real.getName() + "/" + ret;
			}
		}
		return ret;
	}


	/**
	 * 	 * 得到目录下的所有文件
	 * @param baseDir 文件目录
	 * @param baseDir
	 * @return
	 * Created：2013-8-6
	 * @author chaowangbang
	 */
	public static List<File> getDirFiles(File baseDir) {
		ArrayList<File> files = new ArrayList<File>();
		File[] tempFiles = baseDir.listFiles();
		for (File file:tempFiles) {
			//如果是文件 追加
			if (file.isFile()) {
				files.add(file);
				//如果是目录 迭代处理
			}else if (file.isDirectory()) {
				files.addAll(getDirFiles(file));
			}
		}
		return files;
	}

	/**
	 * 在压缩文件中生成一个zip文件条目
	 * @param entryName zip文件条目名称
	 * @param zos zip输出文件流
	 * @param file 要拷贝的文件
	 * Created：2013-8-6
	 * @author chaowangbang
	 * @throws IOException 
	 */
	private static void createZipEntry(String entryName, ZipOutputStream zipOutStream, File file) throws IOException {
		BufferedInputStream buffInStream = null;
		try {
			ZipEntry zipEntry = new ZipEntry(entryName);
			zipEntry.setSize(file.length());
			zipEntry.setTime(file.lastModified());
			zipOutStream.putNextEntry(zipEntry);
			buffInStream = new BufferedInputStream(new FileInputStream(file));
			StreamUtil.transfer(buffInStream,zipOutStream,false);
		}finally {
			StreamUtil.closeStreams(buffInStream);
		}
	}
}
